package com.quik.web.front.action;

import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.quik.common.Constants;
import com.quik.dto.OpenTokenDto;
import com.quik.dto.RelatedItemDto;
import com.quik.entity.BizBilling;
import com.quik.entity.BizBillingRelatedItem;
import com.quik.entity.DtaProduct;
import com.quik.entity.DtaWorker;
import com.quik.entity.SysAccount;
import com.quik.entity.VipAccount;
import com.quik.exception.ErrorCode;
import com.quik.web.front.service.ConsultBillingService;
import com.quik.web.front.service.ConsultBillingServiceImpl;
import com.quik.web.product.service.ProductService;
import com.quik.web.worker.service.WorkerService;

/**
 * 功能说明： 处理与消费、帐单等相关的业务
 * 
 * @author Jenny
 * 
 */
@Controller
@RequestMapping("/consultBilling")
public class ConsultantBillingController {
	private static Logger log = (Logger) Logger
			.getLogger(ConsultantBillingController.class);

	@Autowired
	private ConsultBillingService consultBillingService;

	@Autowired
	private ProductService productService;

	@Autowired
	private WorkerService workerService;

	/**
	 * 消费初始化
	 * 
	 * @return
	 */
	@RequestMapping(value = "initConsume", method = RequestMethod.GET)
	public ModelAndView initConsume() {
		ModelAndView mav = new ModelAndView(
				"/front/consult/billing/consumeList");

		try {
			List categoryList = productService.findCategory();
			mav.addObject("categoryList", categoryList);
		} catch (Exception e) {
			e.printStackTrace();
			log.error("ConsultantBillingConotroller initConsume error: "
					+ e.getMessage());
		}

		return mav;
	}

	/**
	 * 消费
	 * 
	 * @param productNo
	 * @param roomNo
	 * @param tokenNo
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "consume", method = RequestMethod.POST)
	@ResponseBody
	public ResponseEntity<String> consume(String[] productNo, String roomNo,
			String tokenNo, HttpServletRequest request) {
		String result = ErrorCode.SYSTEM_ERROR;
		SysAccount account = (SysAccount) request.getSession().getAttribute(
				Constants.SESSION_ACCOUNT);

		HttpHeaders headers = new HttpHeaders();
		MediaType mediaType = new MediaType("text", "html",
				Charset.forName("UTF-8"));
		headers.setContentType(mediaType);

		try {
			if (consultBillingService.isValid(roomNo, tokenNo)) {
				consultBillingService.consume(productNo, roomNo, tokenNo,
						account.getStaff_no());
				result = "success";
			} else
				result = ErrorCode.CONSULT_CONSUME_TOKEN;
		} catch (Exception e) {
			e.printStackTrace();
			log.error("ConsultantBillingController consume error: "
					+ e.getMessage());
		}
		return new ResponseEntity<String>(result, headers, HttpStatus.OK);
	}

	@RequestMapping(value = "addProductToBilling", method = RequestMethod.POST)
	public ModelAndView addProductToBilling(Integer billingId,
			String[] productNos, Integer[] qtys, String roomNo, String tokenNo,
			HttpServletRequest request) {
		SysAccount account = (SysAccount) request.getSession().getAttribute(
				Constants.SESSION_ACCOUNT);
		try {
			if (consultBillingService.isValid(roomNo, tokenNo)) {
				billingId = consultBillingService.addBillingItemByBillingId(
						billingId, productNos, qtys, roomNo, tokenNo,
						account.getStaff_no());
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return new ModelAndView("redirect:/consultToken/tokenList?billingId="
				+ billingId + "&tokenNo=" + tokenNo);
	}

	@RequestMapping(value = "startProduct", method = RequestMethod.POST)
	public ModelAndView startProduct(Integer billingId, Integer billingItemId, String tokenNo,
			Integer[] serviceIds, String[] workerNos, String[] turnTypes,
			String[] callTurnWorkerNos, HttpServletRequest request) {
		SysAccount account = (SysAccount) request.getSession().getAttribute(
				Constants.SESSION_ACCOUNT);
		try {
			consultBillingService.startProduct(billingItemId, tokenNo, serviceIds,
					workerNos, turnTypes, callTurnWorkerNos, account);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return new ModelAndView("redirect:/consultToken/tokenList?billingId="
				+ billingId + "&tokenNo=" + tokenNo);
	}

	/**
	 * 指定技师界面
	 * 
	 * @param billingItemId
	 * @return
	 */
	@RequestMapping(value = "initService")
	public ModelAndView initService(Integer billingItemId) {
		ModelAndView mav = new ModelAndView("/front/consult/room/worker");

		try {
			List workerTypeList = workerService.findWorkerType(null, null,
					null, null);
			List turnTypeList = consultBillingService.findTurnTypeList();

			mav.addObject("workerStatus", DtaWorker.STATUS_FREE);
			mav.addObject("gender_man", SysAccount.GENDER_MAN);
			mav.addObject("workerTypeList", workerTypeList);

			mav.addObject("turnTypeList", turnTypeList);
		} catch (Exception e) {
			e.printStackTrace();
			log.error("ConsultantBillingController initService error: "
					+ e.getMessage());
		}

		return mav;
	}

	/**
	 * 分配技师
	 * 
	 * @param itemId
	 *            biz_billing_item的id
	 * @param subItemId
	 *            biz_billing_service的id
	 * @param workerNo
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "service", method = RequestMethod.POST)
	@ResponseBody
	public ResponseEntity<String> service(Integer itemId, Integer subItemId,
			String workerNo, String turnType, HttpServletRequest request) {
		String result = "error";
		SysAccount account = (SysAccount) request.getSession().getAttribute(
				Constants.SESSION_ACCOUNT);

		try {
			consultBillingService.service(itemId, subItemId, workerNo,
					turnType, account.getStaff_no());

			result = "success";
		} catch (Exception e) {
			e.printStackTrace();
			log.error("ConsultantBillingController service error: "
					+ e.getMessage());
		}

		return new ResponseEntity<String>(result, HttpStatus.OK);
	}

	/**
	 * 起钟
	 * 
	 * @param item
	 * @param subItem
	 * @param service
	 * @param chess
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "start", method = RequestMethod.POST)
	@ResponseBody
	public OpenTokenDto start(Integer itemId, Integer subItemId,
			String service, String chessRoom, HttpServletRequest request) {
		OpenTokenDto dto = new OpenTokenDto();
		dto.setResult("error");
		SysAccount account = (SysAccount) request.getSession().getAttribute(
				Constants.SESSION_ACCOUNT);

		try {
			String startTime = consultBillingService.start(itemId, subItemId,
					service, chessRoom, account.getStaff_no());

			dto.setResult("success");
			dto.setObj(startTime);
		} catch (Exception e) {
			e.printStackTrace();
			log.error("ConsultantController start error: " + e.getMessage());
		}

		return dto;
	}

	@RequestMapping(value = "startBillingItem", method = RequestMethod.POST)
	@ResponseBody
	public OpenTokenDto startBillingItem(Integer itemId,
			HttpServletRequest request) {
		OpenTokenDto dto = new OpenTokenDto();
		dto.setResult("error");
		SysAccount account = (SysAccount) request.getSession().getAttribute(
				Constants.SESSION_ACCOUNT);

		try {
			String startTime = consultBillingService.startByItemId(itemId,
					account.getStaff_no());
			dto.setResult("success");
			dto.setObj(startTime);
		} catch (Exception e) {
			e.printStackTrace();
			log.error("ConsultantController start error: " + e.getMessage());
		}

		return dto;
	}

	/**
	 * 取消
	 * 
	 * @param itemId
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "cancelOrder", method = RequestMethod.POST)
	public ResponseEntity<String> cancelOrder(String operateAccount,
			String operatePass, Integer itemId, Integer subItemId,
			String chess, String service, HttpServletRequest request) {
		String result = ErrorCode.SYSTEM_ERROR;
		SysAccount account = (SysAccount) request.getSession().getAttribute(
				Constants.SESSION_ACCOUNT);

		// 解决返回中文乱码问题
		HttpHeaders headers = new HttpHeaders();
		MediaType mediaType = new MediaType("text", "html",
				Charset.forName("UTF-8"));
		headers.setContentType(mediaType);

		try {
			if (consultBillingService.isAuth(operateAccount, operatePass)) { // 授权
				if (consultBillingService.isOrder(itemId)) { // 取消权限判断
					consultBillingService.cancelOrder(itemId, subItemId,
							service, chess, account.getStaff_no()); // 待改
					result = "success";
				} else
					result = ErrorCode.CONSULT_CANCEL_ORDER_FAILED;
			} else
				result = ErrorCode.CONSULT_CANCEL_ORDER_PASSWORD_ERROR;

		} catch (Exception e) {
			e.printStackTrace();
			log.error("ConsultantController cancel error: " + e.getMessage());
		}

		return new ResponseEntity<String>(result, headers, HttpStatus.OK);
	}

	/**
	 * 落钟
	 * 
	 * @param itemId
	 * @param subItemId
	 * @param service
	 * @param chessRoom
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "end", method = RequestMethod.POST)
	@ResponseBody
	public OpenTokenDto end(Integer itemId, Integer subItemId, String service,
			String chessRoom, HttpServletRequest request) {
		OpenTokenDto dto = new OpenTokenDto();
		dto.setResult("error");
		SysAccount account = (SysAccount) request.getSession().getAttribute(
				Constants.SESSION_ACCOUNT);

		try {
			String endTime = consultBillingService.end(itemId, subItemId,
					service, chessRoom, account.getStaff_no());

			dto.setObj(endTime);
			dto.setResult("success");
		} catch (Exception e) {
			e.printStackTrace();
			log.error("ConsultantController end error: " + e.getMessage());
		}

		return dto;
	}

	/**
	 * 反落钟 (棋牌类：更新biz_billing_item的状态由结束变为使用中， 清空biz_billing_chess_room中的结束时间)
	 * 
	 * @param itemId
	 * @param subItemId
	 * @param service
	 * @param chessRoom
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "reverseEnd", method = RequestMethod.POST)
	public ResponseEntity<String> reverseEnd(Integer itemId, Integer subItemId,
			String service, String chessRoom, HttpServletRequest request) {
		String result = ErrorCode.SYSTEM_ERROR;
		SysAccount account = (SysAccount) request.getSession().getAttribute(
				Constants.SESSION_ACCOUNT);

		// 解决返回中文乱码问题
		HttpHeaders headers = new HttpHeaders();
		MediaType mediaType = new MediaType("text", "html",
				Charset.forName("UTF-8"));
		headers.setContentType(mediaType);

		try {
			consultBillingService.reverseEnd(itemId, subItemId, service,
					chessRoom, account.getStaff_no());
			result = "success";
		} catch (Exception e) {
			e.printStackTrace();
			log.error("ConsultantController reverseEnd error: "
					+ e.getMessage());
		}
		return new ResponseEntity<String>(result, headers, HttpStatus.OK);
	}

	/**
	 * 退钟
	 * 
	 * @param subItemId
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "quitCall", method = RequestMethod.POST)
	@ResponseBody
	public ResponseEntity<String> quitCall(Integer subItemId,
			HttpServletRequest request) {
		String result = ErrorCode.SYSTEM_ERROR;
		SysAccount account = (SysAccount) request.getSession().getAttribute(
				Constants.SESSION_ACCOUNT);

		// 解决返回中文乱码问题
		HttpHeaders headers = new HttpHeaders();
		MediaType mediaType = new MediaType("text", "html",
				Charset.forName("UTF-8"));
		headers.setContentType(mediaType);

		try {
			consultBillingService.endCall(subItemId, account.getStaff_no());
			result = "success";
		} catch (Exception e) {
			e.printStackTrace();
			log.error("ConsultantController quitCall error: " + e.getMessage());
		}
		return new ResponseEntity<String>(result, headers, HttpStatus.OK);
	}

	/**
	 * 更换技师
	 * 
	 * @param srcWorkerNo
	 * @param workerNo
	 * @param itemId
	 * @param subItemId
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "alterWorker", method = RequestMethod.POST)
	@ResponseBody
	public ResponseEntity<String> alterWorker(String srcWorkerNo,
			String workerNo, Integer itemId, Integer subItemId,
			HttpServletRequest request) {
		String result = ErrorCode.SYSTEM_ERROR;
		SysAccount account = (SysAccount) request.getSession().getAttribute(
				Constants.SESSION_ACCOUNT);

		// 解决返回中文乱码问题
		HttpHeaders headers = new HttpHeaders();
		MediaType mediaType = new MediaType("text", "html",
				Charset.forName("UTF-8"));
		headers.setContentType(mediaType);

		try {
			consultBillingService.exchangeWorker(srcWorkerNo, workerNo, itemId,
					subItemId, account.getStaff_no());
			result = "success";
		} catch (Exception e) {
			e.printStackTrace();
			log.error("ConsultantController alterWorker error: "
					+ e.getMessage());
		}
		return new ResponseEntity<String>(result, headers, HttpStatus.OK);
	}

	/**
	 * 帐单手牌初始化
	 * 
	 * @return
	 */
	@RequestMapping(value = "initRelateBilling", method = RequestMethod.GET)
	public ModelAndView initRelateBilling() {
		ModelAndView mav = new ModelAndView(
				"/front/consult/billing/relateBilling");

		try {
			List relateList = consultBillingService.findRelateBilling(null,
					null);

			mav.addObject("relateList", relateList);
		} catch (Exception e) {
			e.printStackTrace();
			log.error("ConsultantBillingController initRelateBilling error: "
					+ e.getMessage());
		}

		return mav;
	}

	/**
	 * 根据编号及类型查询帐单相关关联信息
	 * 
	 * @param itemNo
	 * @param itemType
	 * @return
	 */
	@RequestMapping(value = "queryRelateBilling", method = RequestMethod.POST)
	@ResponseBody
	public OpenTokenDto queryRelateBilling(String itemNo, Integer itemType) {
		OpenTokenDto dto = new OpenTokenDto();
		dto.setResult("error");

		try {
			List list = consultBillingService.findRelateBilling(itemNo,
					(itemType == -1 ? null : itemType));

			dto.setObj(list);
			dto.setResult("success");
		} catch (Exception e) {
			e.printStackTrace();
			log.error("ConsultantBillingController queryBilling error: "
					+ e.getMessage());
		}

		return dto;
	}

	/**
	 * 关联帐单
	 * 
	 * @param relateNo
	 * @param relateType
	 * @param billingIds
	 * @param billingNos
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "relateBilling", method = RequestMethod.POST)
	@ResponseBody
	public ResponseEntity<String> relateBilling(String relateNo,
			Integer relateType, Integer[] billingIds, String[] billingNos,
			HttpServletRequest request) {
		String result = ErrorCode.SYSTEM_ERROR;
		SysAccount account = (SysAccount) request.getSession().getAttribute(
				Constants.SESSION_ACCOUNT);

		HttpHeaders headers = new HttpHeaders();
		MediaType mediaType = new MediaType("text", "html",
				Charset.forName("UTF-8"));
		headers.setContentType(mediaType);

		try {
			BizBilling bizBilling = consultBillingService.getRelateBilling(
					relateNo, relateType);
			if (consultBillingService.isMasterBilling(bizBilling)) {
				consultBillingService.relateBilling(bizBilling, billingIds,
						billingNos, account.getStaff_no());
				result = "success";
			} else
				result = ErrorCode.CONSULT_RELATE_BILLING;
		} catch (Exception e) {
			e.printStackTrace();
			log.error("ConsultantBillingController relateBilling error: "
					+ e.getMessage());
		}

		return new ResponseEntity<String>(result, headers, HttpStatus.OK);
	}

	/**
	 * 查询帐单初始化
	 * 
	 * @return
	 */
	@RequestMapping(value = "initQueryBilling", method = RequestMethod.GET)
	public ModelAndView initQueryBilling() {
		ModelAndView mav = new ModelAndView(
				"/front/consult/billing/billingList");
		mav.addObject("billingType", BizBillingRelatedItem.ITEM_TYPE_BILLING);
		mav.addObject("tokenType", BizBillingRelatedItem.ITEM_TYPE_TOKEN);
		mav.addObject("roomType", BizBillingRelatedItem.ITEM_TYPE_ROOM);
		return mav;
	}

	/**
	 * 根据条件查询帐单
	 * 
	 * @param tokenNo
	 * @param roomNo
	 * @param isCancel
	 *            如果等于cancel,标识是撤单查询
	 * @return
	 */
	@RequestMapping(value = "queryBilling", method = RequestMethod.POST)
	@ResponseBody
	public RelatedItemDto queryBilling(String itemNo, Integer itemType,
			String isCancel) {
		RelatedItemDto dto = new RelatedItemDto("error");

		try {
			// 帐单与房间、手牌关联项的处理方式不同
			List billingList = null;
			if (isCancel != null && isCancel.equals("cancel")) {
				BizBilling billing = consultBillingService.getRelateBizBilling(
						itemNo, itemType);
				if (billing != null) {
					billingList = new ArrayList();
					billingList.add(billing);
				}
			} else {
				if (itemType.intValue() == BizBillingRelatedItem.ITEM_TYPE_BILLING)
					billingList = consultBillingService
							.findRelateBillingByBillingNo(itemNo);
				else
					billingList = consultBillingService
							.findRelateBillingByItemNo(itemNo, itemType);
			}

			if (billingList != null && !billingList.isEmpty()) {
				// 查询关联手牌
				List tokenList = consultBillingService
						.findRelateTokenByBillingId(billingList);
				// 查询关联房间
				List roomList = consultBillingService
						.findRelateRoomByBillingId(billingList);
				// 查询棋牌消费明细
				List chessList = consultBillingService
						.findChessConsumeByBillingId(billingList);
				// 查询服务消费明细
				List serviceList = consultBillingService
						.findServiceConsumeByBillingId(billingList);
				// 查询其它明细
				List otherList = consultBillingService
						.findOtherConsumeByBillingId(billingList);

				dto.setBillingList(billingList);
				if (billingList != null && !billingList.isEmpty())
					dto.setBillingSize(billingList.size());

				dto.setRoomList(roomList);
				if (roomList != null && !roomList.isEmpty())
					dto.setRoomSize(roomList.size());

				dto.setTokenList(tokenList);
				if (tokenList != null && !tokenList.isEmpty())
					dto.setTokenSize(tokenList.size());

				dto.setServiceList(serviceList);
				if (serviceList != null && !serviceList.isEmpty())
					dto.setServiceSize(serviceList.size());

				dto.setChessList(chessList);
				if (chessList != null && !chessList.isEmpty())
					dto.setChessSize(chessList.size());

				dto.setOtherList(otherList);
				if (otherList != null && !otherList.isEmpty())
					dto.setOtherSize(otherList.size());

				dto.setResult("success");
			} else
				dto.setResult("noData");
		} catch (Exception e) {
			e.printStackTrace();
			log.error("ConsultantBillingController queryBilling error: "
					+ e.getMessage());
		}

		return dto;
	}

	/**
	 * 消费转出
	 * 
	 * @param itemId
	 * @param billingType
	 * @param transferNo
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "transfer", method = RequestMethod.POST)
	@ResponseBody
	public ResponseEntity<String> transfer(Integer itemId, Integer billingType,
			String transferNo, HttpServletRequest request) {
		String result = ErrorCode.SYSTEM_ERROR;
		SysAccount account = (SysAccount) request.getSession().getAttribute(
				Constants.SESSION_ACCOUNT);

		HttpHeaders headers = new HttpHeaders();
		MediaType mediaType = new MediaType("text", "html",
				Charset.forName("UTF-8"));
		headers.setContentType(mediaType);

		try {
			boolean flag = consultBillingService.isValidBilling(billingType,
					transferNo);
			if (flag) {
				consultBillingService.transfer(itemId, billingType, transferNo,
						account.getStaff_no());
				result = "success";
			} else
				result = ErrorCode.CONSULT_TRANSFER_ORDER_INVALIDBILLING;
		} catch (Exception e) {
			e.printStackTrace();
			log.error("ConsultantBillingController transfer error: "
					+ e.getMessage());
		}

		return new ResponseEntity<String>(result, headers, HttpStatus.OK);
	}

	/**
	 * 开发票初始化
	 * 
	 * @return
	 */
	@RequestMapping(value = "initInvoice", method = RequestMethod.GET)
	public String initInvoice() {
		return "/front/consult/billing/addInvoice";
	}

	/**
	 * 开发票
	 * 
	 * @param invoiceNo
	 * @param invoiceTitle
	 * @param invoiceAmount
	 * @param actualAmount
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "addInvoice", method = RequestMethod.POST)
	public ResponseEntity<String> addInvoice(String invoiceNo,
			String invoiceTitle, String invoiceAmount, String actualAmount,
			HttpServletRequest request) {
		String result = ErrorCode.SYSTEM_ERROR;
		SysAccount account = (SysAccount) request.getSession().getAttribute(
				Constants.SESSION_ACCOUNT);

		HttpHeaders headers = new HttpHeaders();
		MediaType mediaType = new MediaType("text", "html",
				Charset.forName("UTF-8"));
		headers.setContentType(mediaType);

		try {
			consultBillingService.addInvoice(invoiceNo, invoiceTitle,
					invoiceAmount, actualAmount, account.getStaff_no());
			result = "success";
		} catch (Exception e) {
			e.printStackTrace();
			log.error("ConsultangBillingController addInvoice error: "
					+ e.getMessage());
		}

		return new ResponseEntity<String>(result, headers, HttpStatus.OK);
	}

	/**
	 * 设置营业日
	 * 
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "setBusinessDay", method = RequestMethod.POST)
	public ResponseEntity<String> setBusinessDay(HttpServletRequest request) {
		String result = ErrorCode.SYSTEM_ERROR;
		SysAccount account = (SysAccount) request.getSession().getAttribute(
				Constants.SESSION_ACCOUNT);

		HttpHeaders headers = new HttpHeaders();
		MediaType mediaType = new MediaType("text", "html",
				Charset.forName("UTF-8"));
		headers.setContentType(mediaType);

		try {
			consultBillingService.updateBusinessDay(account.getStaff_no());
			result = ErrorCode.CONSULT_SET_BUSINESS_SUCCESS;
		} catch (Exception e) {
			e.printStackTrace();
			log.error("ConsultantBillingController setBusinessDay error: "
					+ e.getMessage());
		}
		return new ResponseEntity<String>(result, headers, HttpStatus.OK);
	}

	/**
	 * 撤单初始化
	 * 
	 * @return
	 */
	@RequestMapping(value = "initRemoveOrder", method = RequestMethod.GET)
	public ModelAndView initRemoveOrder() {
		ModelAndView mav = new ModelAndView(
				"/front/consult/billing/removeOrder");
		mav.addObject("IF_MASTER_YES", BizBilling.MASTER_YES);
		mav.addObject("billingType", BizBillingRelatedItem.ITEM_TYPE_BILLING);
		mav.addObject("tokenType", BizBillingRelatedItem.ITEM_TYPE_TOKEN);
		mav.addObject("roomType", BizBillingRelatedItem.ITEM_TYPE_ROOM);
		return mav;
	}

	/**
	 * 撤单
	 * 
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "cancelAll", method = RequestMethod.POST)
	public ResponseEntity<String> cancelAll(String billingIds,
			String operateAccount, String operatePass,
			HttpServletRequest request) {
		String result = ErrorCode.SYSTEM_ERROR;
		SysAccount account = (SysAccount) request.getSession().getAttribute(
				Constants.SESSION_ACCOUNT);

		// 解决返回中文乱码问题
		HttpHeaders headers = new HttpHeaders();
		MediaType mediaType = new MediaType("text", "html",
				Charset.forName("UTF-8"));
		headers.setContentType(mediaType);

		try {
			if (consultBillingService.isAuth(operateAccount, operatePass)) { // 授权
				consultBillingService.cancelAll(billingIds,
						account.getStaff_no()); // 待改
				result = "success";
			} else
				result = ErrorCode.CONSULT_CANCEL_ORDER_PASSWORD_ERROR;
			result = "success";
		} catch (Exception e) {
			e.printStackTrace();
			log.error("ConsultantBillingController cancelAll error: "
					+ e.getMessage());
		}
		return new ResponseEntity<String>(result, headers, HttpStatus.OK);
	}

	/**
	 * 结帐初始化
	 * 
	 * @return
	 */
	@RequestMapping(value = "initPay", method = RequestMethod.GET)
	public ModelAndView initPay() {
		ModelAndView mav = new ModelAndView("/front/consult/billing/billing");

		try {
			List billingList = consultBillingService.findActiveBillingList();

			mav.addObject("billingList", billingList);
			mav.addObject("master", BizBilling.MASTER_YES);
		} catch (Exception e) {
			e.printStackTrace();
			log.error("ConsultantBillingController initPay error: "
					+ e.getMessage());
		}

		return mav;
	}

	/**
	 * 手牌、房间查询未结帐帐单
	 * 
	 * @param tokenNo
	 * @param roomNo
	 * @return
	 */
	@RequestMapping(value = "queryPayBilling", method = RequestMethod.POST)
	@ResponseBody
	public RelatedItemDto queryPayBilling(String tokenNo, String roomNo) {
		String result = "error";
		RelatedItemDto dto = new RelatedItemDto(result);

		try {
			List billingList = new ArrayList();
			BizBilling billing = null;
			if (tokenNo != null && tokenNo.trim().length() > 0) {
				billing = consultBillingService.getRelateBilling(tokenNo,
						BizBillingRelatedItem.ITEM_TYPE_TOKEN);
				if (billing != null)
					billingList.add(billing);
			} else if (roomNo != null && roomNo.trim().length() > 0) {
				billing = consultBillingService.getRelateBilling(roomNo,
						BizBillingRelatedItem.ITEM_TYPE_ROOM);
				if (billing != null)
					billingList.add(billing);
			} else
				billingList = consultBillingService.findActiveBillingList();

			if (billingList != null && !billingList.isEmpty()) {
				dto.setBillingSize(billingList.size());
				dto.setBillingList(billingList);
			}
			dto.setResult("success");
		} catch (Exception e) {
			log.error("ConsultantBillingController queryPayBilling error: "
					+ e.getMessage());
		}

		return dto;
	}

	/**
	 * 计算帐单（根据编号查询帐单项，并进行批价计算）
	 * 
	 * @param billingIdBox
	 * @return
	 */
	@RequestMapping(value = "calcBilling", method = RequestMethod.POST)
	public ModelAndView calcBilling(String[] billingNoBox) {
		ModelAndView mav = new ModelAndView("/front/consult/billing/pay");

		try {
			if (billingNoBox != null) {
				List billingList = consultBillingService
						.findAllBillingListByBillingId(billingNoBox);
				if (billingList != null && !billingList.isEmpty()) {
					String billingIds = "";
					for (Iterator its = billingList.iterator(); its.hasNext();) {
						BizBilling billing = (BizBilling) its.next();
						billingIds += billing.getId() + ";";
					}
					// 消费
					List serviceList = consultBillingService
							.findServiceConsumeByBillingId(billingList);
					List chessList = consultBillingService
							.findChessConsumeByBillingId(billingList);
					List otherList = consultBillingService
							.findOtherConsumeByBillingId(billingList);

					int productPriceType = consultBillingService
							.getProductPriceType();
					// 批价
					consultBillingService.calcServicePrice(serviceList,
							productPriceType);
					consultBillingService.calcChessPrice(chessList,
							productPriceType);
					consultBillingService.calcOtherPrice(otherList);

					// 判断是否还有未结束的帐单 （先判断服务类，再判断棋牌类）
					boolean flag = consultBillingService.batchEndStatus(
							serviceList, chessList);

					// 计算总价，VIP总价，实际总价
					if (flag) {
						ConsultBillingServiceImpl.BillingPrice totalPrice = consultBillingService
								.sum(serviceList, chessList, otherList);
						mav.addObject("totalPrice", totalPrice);
					}

					mav.addObject("payAuthFlag", flag);
					mav.addObject("serviceList", serviceList);
					mav.addObject("chessList", chessList);
					mav.addObject("otherList", otherList);
					mav.addObject("billingIds",
							billingIds.substring(0, billingIds.length() - 1));
					mav.addObject("able", DtaProduct.OPTION_FOR_YES);
				}
			}
			List paymentTypeList = consultBillingService.findPaymentTypeList();
			mav.addObject("paymentTypeList", paymentTypeList);
		} catch (Exception e) {
			e.printStackTrace();
			log.error("ConsultangBillingController calcBilling error: "
					+ e.getMessage());
		}

		return mav;
	}

	/**
	 * 验证会员卡号
	 * 
	 * @param vipCard
	 * @return
	 */
	@RequestMapping(value = "checkMember", method = RequestMethod.POST)
	@ResponseBody
	public OpenTokenDto checkMember(String vipCard) {
		OpenTokenDto dto = new OpenTokenDto();

		try {
			VipAccount vipAccount = consultBillingService
					.getVipAccount(vipCard);
			if (vipAccount == null) {
				dto.setResult(ErrorCode.MEMBER_ACCOUNT_INVALID);
			} else {
				if (consultBillingService.compareTime(vipAccount
						.getTake_eff_start_time()) <= 0) {
					if (consultBillingService.compareTime(vipAccount
							.getTake_eff_end_time()) >= 0) {
						dto.setResult("success");
						dto.setObj(vipAccount);
					} else
						dto.setResult(ErrorCode.MEMBER_ACCOUNT_EXPIRED);
				} else
					dto.setResult(ErrorCode.MEMBER_ACCOUNT_INEFFECTIVE);
			}
		} catch (Exception e) {
			e.printStackTrace();
			log.error("ConsultantBillingController checkMember error: "
					+ e.getMessage());
		}

		return dto;
	}

	/**
	 * 结帐
	 * 
	 * @param paymentType
	 * @param totalPrice
	 * @param vipPrice
	 * @param receivePrice
	 * @param actualAmount
	 * @param returnAmount
	 * @param vipCard
	 * @param billingItems
	 * @param billingIds
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "pay", method = RequestMethod.POST)
	@ResponseBody
	public ResponseEntity<String> pay(String paymentType, Integer totalPrice,
			Integer vipPrice, Integer receivePrice, Integer actualAmount,
			Integer returnAmount, String vipCard, String[] billingItems,
			String billingIds, HttpServletRequest request) {
		String result = ErrorCode.PAY_MONEY_ERROR;
		SysAccount account = (SysAccount) request.getSession().getAttribute(
				Constants.SESSION_ACCOUNT);

		HttpHeaders headers = new HttpHeaders();
		MediaType mediaType = new MediaType("text", "html",
				Charset.forName("UTF-8"));
		headers.setContentType(mediaType);

		try {
			List billingList = consultBillingService
					.constructBizBillingList(billingIds);
			List serviceList = consultBillingService
					.findServiceConsumeByBillingId(billingList);
			List chessList = consultBillingService
					.findChessConsumeByBillingId(billingList);
			List otherList = consultBillingService
					.findOtherConsumeByBillingId(billingList);

			int productPriceType = consultBillingService.getProductPriceType();
			// 第一批价
			consultBillingService.calcServicePrice(serviceList,
					productPriceType);
			consultBillingService.calcChessPrice(chessList, productPriceType);
			consultBillingService.calcOtherPrice(otherList);

			// 根据前端操作信息更新对应的信息，并进行第二次计算（主要是打折、赠送）
			consultBillingService.calcPrice(serviceList, chessList, otherList,
					billingItems);

			// 判断是否还有未结束的帐单 （先判断服务类，再判断棋牌类）
			boolean flag = consultBillingService.batchEndStatus(serviceList,
					chessList);

			// 计算总价，VIP总价，实际总价
			if (flag) {
				ConsultBillingServiceImpl.BillingPrice billingPrice = consultBillingService
						.sum(serviceList, chessList, otherList);
				if (billingPrice.getTotalPrice() == totalPrice.intValue()
						&& billingPrice.getVipPrice() == vipPrice.intValue()) {
					if ((vipCard != null && vipCard.length() > 0)) {
						if (billingPrice.getVipPrice() == receivePrice
								.intValue()) {
							// 开始保存
							consultBillingService
									.addPay(paymentType, billingPrice,
											actualAmount, returnAmount,
											vipCard, billingList, serviceList,
											chessList, otherList,
											account.getStaff_no());
							consultBillingService.updateTokenOrRoomStatus(
									billingIds, account.getStaff_no());
							result = "success";
						}
					} else {
						if (billingPrice.getActualPrice() == receivePrice
								.intValue()) {
							consultBillingService
									.addPay(paymentType, billingPrice,
											actualAmount, returnAmount,
											vipCard, billingList, serviceList,
											chessList, otherList,
											account.getStaff_no());
							consultBillingService.updateTokenOrRoomStatus(
									billingIds, account.getStaff_no());
							result = "success";
						}
					}
				}
			}
		} catch (Exception e) {
			result = ErrorCode.SYSTEM_ERROR;
			e.printStackTrace();
			log.error("ConsultantBillingController consume error: "
					+ e.getMessage());
		}
		return new ResponseEntity<String>(result, headers, HttpStatus.OK);
	}
}
